﻿using Lazy.Captcha.Core;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using RuoVea.DynamicWebApi;
using RuoVea.ExDto;
using RuoVea.ExEnum;
using RuoVea.ExFilter;
using RuoVea.ExIdGen;
using RuoVea.ExJwtBearer;
using RuoVea.ExSugar;
using RuoVea.ExUtil;
using RuoVea.ExUtil.Exceptions;
using RuoVea.OmiApi.Auth.Const;
using RuoVea.OmiApi.Auth.Entitys;
using RuoVea.OmiApi.Auth.Language;
using RuoVea.OmiApi.Auth.Service.Dto;
using RuoVea.OmiApi.Config.Service;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using exDtoi18n = RuoVea.ExDto.Language.i18n;

namespace RuoVea.OmiApi.Auth.Service;

/// <summary>
/// 登录授权相关服务 🔷
/// </summary>
[ApiExplorerSettings(GroupName = "system")]
public class AuthService : IApplicationService
{
    private readonly ICurrentUserManager _currentUserManager;
    private readonly ICurrentUser _currentUser;
    private readonly SugarRepository<SysUser> _sysUser;
    private readonly SysConfigService _sysConfigService;
    private readonly IHttpContextAccessor _httpContextAccessor;
    private readonly IJwtHelper _jwtHelper;
    private readonly ICaptcha _captcha;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="httpContextAccessor"></param>
    /// <param name="sysUser"></param>
    /// <param name="sysConfigService"></param>
    /// <param name="currentUserManager"></param>
    /// <param name="jwtHelper"></param>
    /// <param name="currentUser"></param>
    /// <param name="captcha"></param>
    public AuthService(IHttpContextAccessor httpContextAccessor, SugarRepository<SysUser> sysUser, SysConfigService sysConfigService, ICurrentUserManager currentUserManager, IJwtHelper jwtHelper, ICurrentUser currentUser, ICaptcha captcha)
    {
        _httpContextAccessor = httpContextAccessor;
        _sysUser = sysUser;
        _sysConfigService = sysConfigService;
        _currentUserManager = currentUserManager;
        _jwtHelper = jwtHelper;
        _currentUser = currentUser;
        _captcha = captcha;
    }

    /// <summary>
    /// 用户登录🔹
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    [AllowAnonymous]
    [DisplayName("登录系统")]
    public async Task<string> LoginAsync([Required] LoginInput data)
    {
        if (await GetCaptchaOpenFlag())
        {
            if (data.CodeId <= 0 || data.Code.IsNullOrWhiteSpace())
                throw new ParamiterException(i18n.captcha_incorrect);

            if (!await VerificationCode(data))
                throw new ParamiterException(i18n.captcha_incorrect);
        }
        //// 获取加密后的密码
        //var encryptPasswod = data.Password;

        // 判断用户名和密码是否正确(排除全局多租户过滤器)Filter(null,true)
        var user = await _currentUserManager.GetUserByAccountAndPassword(data.Account, data.Password, data.isEncPass);
        if (user == null)
            throw new ParamiterException(ErrorEnum.D1000.GetDescription(exDtoi18n.ResourceManager));

        // 验证账号是否被冻结
        if (user.IsDisable == YesOrNot.Y)
        {
            //await CreateVisLog(user.Name, data.Account, YesOrNot.N, ErrorEnum.D1017.GetDescription());
            throw new ParamiterException(ErrorEnum.D1017.GetDescription(exDtoi18n.ResourceManager));
        }
        var accessToken = _currentUserManager.IssueToken(user, null);

        // 设置Swagger自动登录
        _httpContextAccessor.HttpContext?.SigninToSwagger(accessToken);

        // 生成刷新Token令牌
        var refreshToken = _jwtHelper.GenerateRefreshToken(accessToken);
        // 设置刷新Token令牌
        _httpContextAccessor.HttpContext.Response.Headers["x-access-token"] = refreshToken;

        var httpContext = _httpContextAccessor.HttpContext;
        await _sysUser.Context.Updateable(new SysUser
        {
            Id = user.Id,
            LastLoginIp = httpContext.GetLocalIpAddressToIPv4(),
            LastLoginTime = DateTime.Now
        })
       .UpdateColumns(m => new { m.LastLoginTime, m.LastLoginIp }).ExecuteCommandAsync();

        return accessToken;
    }
    /// <summary>
    /// 获取刷新Token🔹
    /// </summary>
    /// <param name="accessToken"></param>
    /// <returns></returns>
    [DisplayName("获取刷新Token")]
    public string GetRefreshToken(string accessToken)
    {
        return _jwtHelper.GenerateRefreshToken(accessToken);
    }

    /// <summary>
    /// 获取登录账号🔹
    /// </summary>
    /// <returns></returns>
    [DisplayName("登录系统")]
    public async Task<LoginUserOutput> GetUserInfoAsync()
    {
        var user = await _sysUser.GetFirstAsync(u => u.Id == _currentUser.UserId);
        if (user == null)
            throw new ArgumentNullException(ErrorEnum.D1011.GetDescription(exDtoi18n.ResourceManager));

        //// 获取机构
        //var org = await _sysUser.ChangeRepository<SugarRepository<SysOrg>>().GetFirstAsync(u => u.Id == user.OrgId);
        //// 获取职位
        //var pos = await _sysUser.ChangeRepository<SugarRepository<SysPos>>().GetFirstAsync(u => u.Id == user.PosId);
        //// 获取拥有按钮权限集合
        //var buttons = await _sysMenuService.GetOwnBtnPermList();

        return new LoginUserOutput
        {
            Account = user.Account,
            RealName = user.RealName,
            Avatar = user.Avatar,
            AccountType = user.AdminType,
            Signature = user.Signature,

            //OrgId = user.OrgId,
            //OrgName = org?.Name,
            //PosName = pos?.Name,
            //Buttons = buttons
        };
    }
    ///// <summary>
    ///// 获取当前登录用户信息
    ///// </summary>
    ///// <returns></returns>
    //public async Task<LoginOutput> GetLoginUserAsync()
    //{
    //    var user = await _sysUserRep.GetFirstAsync(u => u.Id == _currentUser.UserId);
    //    if (user == null)
    //        throw new ArgumentException(ErrorEnum.D1011.GetDescription());
    //    var httpContext = _httpContextAccessor.HttpContext;
    //    var loginOutput = user.Adapt<LoginOutput>();
    //    // 角色信息
    //    loginOutput.Roles = await _sysRoleService.GetUserRoleList(user.Id);
    //    // 权限信息
    //    loginOutput.Permissions = await _sysMenuService.GetLoginPermissionList(user.Id);
    //    loginOutput.Permissions = new List<string> { "list.add", "list.edit", "list.delete", "user.add", "user.edit", "user.delete" };
    //    //// 系统所有权限信息
    //    //loginOutput.AllPermissions = await _sysMenuService.GetAllPermissionList();
    //    //// 数据范围信息(机构Id集合)
    //    //loginOutput.DataScopes = await _sysUserService.GetUserDataScopeIdList(userId);
    //    loginOutput.Menus = await _sysMenuService.GetLoginMenusSCUI(user.Id, "");
    //    return loginOutput;
    //}

    /// <summary>
    /// 退出🔹
    /// </summary>
    /// <returns></returns>
    [DisplayName("退出系统")]
    [AllowAnonymous]
    public void LogoutAsync()
    {
        _httpContextAccessor.HttpContext?.SignoutToSwagger();
        _httpContextAccessor.HttpContext.Response.Headers["access-token"] = "invalid token";
    }
    /// <summary>
    /// 获取登录配置🔹
    /// </summary>
    /// <returns></returns>
    [AllowAnonymous]
    [DisplayName("获取登录配置")]
    public async Task<dynamic> GetLoginConfig()
    {
        var secondVerEnabled = await _sysConfigService.GetConfigCache(CacheConst.SysSecondVer);
        var captchaEnabled = await GetCaptchaOpenFlag();
        var watermarkEnabled = await _sysConfigService.GetConfigCache(CacheConst.SysWatermark);
        var watermark = await _sysConfigService.GetConfigCache(CacheConst.SysWebWatermark);

        return new
        {
            SecondVerEnabled = string.IsNullOrWhiteSpace(secondVerEnabled) ? false : (secondVerEnabled.Equals("true", StringComparison.OrdinalIgnoreCase) ? true : false),
            CaptchaEnabled = captchaEnabled,
            WatermarkEnabled = string.IsNullOrWhiteSpace(watermarkEnabled) ? false : (watermarkEnabled.Equals("true", StringComparison.OrdinalIgnoreCase) ? true : false),
            watermark = watermark,
        };
    }

    /// <summary>
    /// 获取验证码开关标识🔹
    /// </summary>
    /// <returns></returns>
    [AllowAnonymous]
    public async Task<bool> GetCaptchaOpenFlag()
    {
        return await _sysConfigService.GetCaptchaOpenFlag();
    }
    /// <summary>
    /// 获取验证码🔹
    /// </summary>
    /// <returns></returns>
    [AllowAnonymous]
    [DisplayName("获取验证码")]
    public dynamic GetCaptcha()
    {
        var codeId = IdGenerator.Id;
        var captcha = _captcha.Generate(codeId.ToString());
        return new { Id = codeId, Img = captcha.Base64 };
    }

    /// <summary>
    /// 校验验证码🔹
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [NonAction]
    public async Task<bool> VerificationCode(LoginInput input)
    {
        return await Task.Run(() => { return _captcha.Validate(input.CodeId + "", input.Code); });
        //var code = CacheFactery.Cache.Read(CacheConst.Cache_Key_Code + input.CodeId);
        //if (!string.Equals(code, input.Code, StringComparison.CurrentCultureIgnoreCase)) return false;
        //return await Task.FromResult(true);
    }
}
